<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <script>
        //                 原型
        // 1.定义：原型是function对象的一个属性，它定义了构造函数制造出的对象的公共祖先。
        // 通过该构造函数产生的对象，可以继承该原型的属性和方法。原型也是对象。
        // 2.利用原型特点和概念，可以提取共有属性。
        // 3.对象如何查看原型-->隐式属性_proto_
        // 4.对象如何查看对象的构造函数-->constructor


        // Person.prototype   --原型
        // Person.prototype = {}   是祖先

        // A.prototype = {
        //     LastName: 'huang'
        // }
        // A.prototype.say = function() {
        //     console.log('haha');
        // }




        // function A(name, age, sex) {
        //     this.name = name;
        //     this.age = age;
        //     this.sex = sex;
        // }
        // var a = new A('shulang', 66, 'male');



        // Car.prototype = {
        //     height: 1400,
        //     lang: 4900,
        //     carName: 'BMW'
        // }

        // function Car(color, owner) {
        //     this.owner = owner;
        //     this.color = color;
        // }

        // var car = new Car('red', 'zhu');
        // var car1 = new Car('black', 'huang');
        // console.log(car);
        // console.log(car1);



        // __proto__   里面放该对象的原型
        // Person.prototype.name = 'sunny';

        // function Person() {
        //     // var this = {__proto__: Person.prototype}
        // }
        // var person = new Person();
        // Person.prototype = {
        //     name: 'cheey'
        // }
        // console.log(person.name);//这个时候指向的还是suuny
        // var person1 = new Person();//换了个原型
        // console.log(person1.name);//指向cheey



        // var obj = {
        //     name: 'a'
        // };
        // var obj1 = obj;
        // obj = {
        //     name: 'b'
        // };
        // console.log(obj1.name);
        // console.log(obj.name);





        // constructor  会返回构造这个对象的构造函数
        // function Test() {}
        // let test = new Test();
        // console.log(test.constructor);




        //      原型链
        // 如何构成原型链?
        // 原型链上属性的增删改查
        // 绝大多数对象最终都会继承自Object.prototype
        // Object.create(原型)

        // Grand.prototype.__proto__ = Object.prototype
        // Grand.prototype.lastName = 'qi';

        // function Grand() {

        // }
        // var grand = new Grand();
        // Father.prototype = grand;

        // function Father() {
        //     this.name = 'huilong';
        // }
        // var father = new Father();
        // Son.prototype = father;

        // function Son() {
        //     this.age = '18';
        // }
        // var son = new Son();





        // a.sayName()
        // sayName里面的this指向谁，谁调用的这个方法，this就指向谁
        // Person.prototype = {
        //     name: 'a',
        //     sayName: function() {
        //         console.log(this.name);
        //     }
        // }

        // function Person() {
        //     this.name = 'b';
        // }

        // var person = new Person();




        // Object.create(原型);
        // var obj = Object.create(原型);

        // var obj = {
        //     name: 'sunny',
        //     age: 123
        // };
        // var obj1 = Object.create(obj);
        // var obj = Object.create(null);//没有原型



        // Person.prototype = {
        //     toString: function() {
        //         return 'hehe';
        //     }
        // }

        // function Person() {

        // }
        // var person = new Person();
        // 这种和终端上名字一样但实现不同功能，叫方法的重写


        // Object.prototype.toString
        // Number.prototype.toString
        // Array.prototype.toString
        // Boolean.prototype.toString
        // String.prototype.toString



        // var obj = Object.create(null);
        // obj.toString = function() {
        //     return '小黄肾好';
        // }
        // document.write(obj);




        // Math.ceil(123.234);向上取整
        // Math.floor(123.234);向下取整
        // Math.random();0-1之间的随机数
        // toFixed();把数字转换为字符串， 结果的小数点后有指定位数的数字：
        // var num = 5.56789;
        // var n = num.toFixed(2);
        // n 输出结果:5.57

        //100以内的随机数
        // for (var i = 0; i < 20; i++) {
        //     var num = Math.floor(Math.random() * 100);
        //     console.log(num);
        // }
        // 可正常计算的部分，小数点前十六位后十六位


        // var demo = {
        //     lastName: 'deng'
        // }
        // var obj = Object.create(demo); 
        //能创建一个对象，必须得添加对象的原型，可以传第二个参数(属性的特性)


        // 一旦经历了var的操作，所得出的属性，window，这种属性叫做不可配置的属性
        // 不可配置的属性，delete不掉


        // call/apply
        // function Person(name, age) {
        //     // this = obj
        //     this.name = name;
        //     this.age = age;
        // }
        // var person = new Person();
        // var obj = {}
        // Person.call(obj,'huang',40);
        //Person中的this指向obj,obj后面的会被当做实参传进形参



        // function Wheel(wheelSize, style) {
        //     this.wheelSize = wheelSize;
        //     this.style = style;
        // }

        // function Sit(c, sitColor) {
        //     this.c = c;
        //     this.sitColor = sitColor;
        // }

        // function Model(height, width, len) {
        //     this.height = height;
        //     this.width = width;
        //     this.len = len;
        // }

        // function Car(wheelSize, style, c, sitColor, height, width, len) {
        //     Wheel.apply(this, [wheelSize, style]);
        //     Sit.call(this, c, sitColor);
        //     Model.call(this, height, width, len);
        // }
        // var car = new Car(100, '花色', '真皮', 'red', 1800, 1900, 4900);

        // call/apply     
        // 作用：改变this指向   
        // 区别：传参列表不一样

        //call:需要把实参按照形参的个数传进去
        //apply:需要传一个arguments(形参数组)

        //改变this指向的方法有哪些？区别是什么？
        // call，apply 在函数执行时改变this指向，传参方式不同，call传入多个参数，apply传入数组
        // bind，返回一个带有明确this指向的函数。
        // new，函数执行后返回一个对象，this指向被返回的对象。
    </script>
</body>

</html>